import pylab;
import scipy.interpolate;
from PyQt4 import QtCore, QtGui;

class AnimationGraph:
    def __init__(self):
        self.animType = QtCore.QEasingCurve;
        self.token = None;
    
    def animateNodesPos(self, graphScene, nodes, aPosEnd, nDuration, animType):
        self.aNewPos, self.aOldPos = aPosEnd, [];
        self.aAnimNodes, self.aNodes = [], nodes;
        self.graphScene = graphScene;
        if len(nodes)==0: return;
        for i in range(len(nodes)):
            self.animNode = QtCore.QPropertyAnimation(nodes[i], "pos");
            self.animNode.setDuration(nDuration);
            self.aOldPos.append(nodes[i].pos());
            self.animNode.setStartValue(nodes[i].pos());
            self.animNode.setEndValue(aPosEnd[i]);
            self.animNode.setEasingCurve(animType);
            self.aAnimNodes.append(self.animNode);
            self.aAnimNodes[len(self.aAnimNodes)-1].start();
        QtCore.QObject.connect(self.aAnimNodes[0], QtCore.SIGNAL("finished()"), 
                               self.animNodesPosFinished);
        
    def animNodesPosFinished(self):
        self.graphScene.moveNodes(self.aNodes, self.aOldPos, self.aNewPos);
            
    def animTransition(self, token, pathPts, nDuration, animType, bSpline=False, bReverse=False):
        self.qPath = QtGui.QPainterPath();
        self.pathPolygon = QtGui.QPolygonF();
        self.token = token;
        if bSpline==False:
            #Generate Spline Path (Asuming only CtrlPts were given)
            x, y = [], [];
            for i in range(len(pathPts)):
                x.append(pathPts[i].x());
                y.append(pathPts[i].y());                    
            try:
                tck,u = scipy.interpolate.splprep([x,y],k=2); #@UnusedVariable
            except:
                return "Error with the Spline Preparation";
            else:
                unew = pylab.linspace(0,1,50);
                out = scipy.interpolate.splev(unew,tck);
                for i in range(len(out[0])):
                    self.pathPolygon.append(QtCore.QPointF(out[0][i], out[1][i]));
                self.qPath.moveTo(QtCore.QPointF(pathPts[0].x(), pathPts[0].y()));
                self.qPath.addPolygon(self.pathPolygon);
        else:
            #Spline (Asuming QPainterPath is given)
            self.qPath = pathPts;
        #Make the Path Animation
        nSize = 100.0;
        self.animTrans = QtCore.QPropertyAnimation(token, "pos");
        self.animTrans.setDuration(nDuration);
        if not bReverse:
            self.animTrans.setStartValue(self.qPath.pointAtPercent(0.0));
            for i in range(int(nSize)):
                self.animTrans.setKeyValueAt(i/nSize, self.qPath.pointAtPercent(i/nSize));
            self.animTrans.setEndValue(self.qPath.pointAtPercent(1.0));
        else:
            self.animTrans.setStartValue(self.qPath.pointAtPercent(1.0));
            for i in range(int(nSize)):
                self.animTrans.setKeyValueAt(i/nSize, self.qPath.pointAtPercent(1-i/nSize));
            self.animTrans.setEndValue(self.qPath.pointAtPercent(0.0));
        self.animTrans.setEasingCurve(animType);
        self.animTrans.start();
        QtCore.QObject.connect(self.animTrans, QtCore.SIGNAL("finished()"), 
                               self.animTransFinished);
        
    def animTransFinished(self):
        self.token.setVisible(False);
    